package com.yanqu.road.server.gameplayer.module.activity.sonhai;

import com.yanqu.road.dao.impl.activity.sonhai.SonHaiServerUserDataDaoImpl;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.sonhai.config.*;
import com.yanqu.road.entity.activity.sonhai.data.SonHaiServerUserData;
import com.yanqu.road.entity.activity.sonhai.data.SonHaiUserMallData;
import com.yanqu.road.entity.activity.sonhai.enums.SonHaiPlotTypeEnum;
import com.yanqu.road.entity.activity.springdraw.data.SpringDrawUserData;
import com.yanqu.road.entity.config.patrons.PatronsInfo;
import com.yanqu.road.entity.config.skill.SkillInfo;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.entity.player.UserPatronsSkill;
import com.yanqu.road.exception.BusinessException;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.activity.DaoMuProto;
import com.yanqu.road.pb.activity.SonHaiProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.VipMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.activity.sonhai.SonHaiActivityMgr;
import com.yanqu.road.server.manger.activity.sonhai.pb.SonHaiActivityPb;
import com.yanqu.road.server.manger.config.PatronsMgr;
import com.yanqu.road.server.manger.config.SkillMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class SonHaiActivityModule extends GeneralModule {

    private Map<Integer, SonHaiServerUserData> userDataMap = new ConcurrentHashMap<>();

    public SonHaiActivityModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        SonHaiServerUserDataDaoImpl dao = new SonHaiServerUserDataDaoImpl();
        List<ActivityInfo> activityList = NormalActivityMgr.getOpenActivityInfoList(eActivityType.SonHai.getValue());
        for (ActivityInfo activityInfo : activityList) {
            SonHaiServerUserData userData = dao.getSonHaiServerUserData(activityInfo.getActivityId(), this.getUserId());
            if (userData != null) {
                this.userDataMap.put(userData.getActivityId(), userData);
            }
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        SonHaiServerUserDataDaoImpl dao = new SonHaiServerUserDataDaoImpl();
        for (SonHaiServerUserData userData : this.userDataMap.values()) {
            if (userData.isInsertOption()) {
                dao.add(userData);
            } else if (userData.isUpdateOption()) {
                dao.update(userData);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        //判断系统是否解锁
        if (SystemOpenMgr.systemOpen(player, eSystemId.SonHai.getValue())) {
            //推送活动配置
            this.syncConfig();
            //通知跨服，登录后处理
            this.crossAfterLoginHandle();
        }
    }

    /**
     * 跨服登录后处理
     */
    private void crossAfterLoginHandle() {
        for (SonHaiServerUserData userData : this.userDataMap.values()) {
            SonHaiProto.SonHaiCrossAfterLoginHandleReqMsg.Builder builder = SonHaiProto.SonHaiCrossAfterLoginHandleReqMsg.newBuilder();
            builder.setActivityId(userData.getActivityId());
            //推送
//            player.sendPacket(Protocol.C2_SON_HAI_AFTER_LOGIN_HANDLE, builder);
            player.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_AFTER_LOGIN_HANDLE, builder, builder.getActivityId());
        }
    }

    /**
     * 初始化玩家
     * @param activityId
     * @return
     */
    private synchronized SonHaiServerUserData initUserData(int activityId) {
        SonHaiServerUserData userData = this.userDataMap.get(activityId);
        if (userData == null) {
            userData = new SonHaiServerUserData(activityId, player.getUserId());
            this.userDataMap.put(activityId, userData);
        }
        return userData;
    }

    /**
     * 获取玩家数据
     * @param activityId
     * @return
     */
    public SonHaiServerUserData getUserData(int activityId) {
        SonHaiServerUserData userData = this.userDataMap.get(activityId);
        if (userData == null) {
            userData = this.initUserData(activityId);
        }
        return userData;
    }

    /**
     * 同步配置
     */
    public void syncConfig() {
        //同步配置
        Map<Integer, SonHaiConfig> configMap = SonHaiActivityMgr.getActivityConfigMap();
        for (SonHaiConfig config : configMap.values()) {
            SonHaiProto.SonHaiSyncConfigMsg.Builder builder = SonHaiProto.SonHaiSyncConfigMsg.newBuilder();
            builder.setActivityId(config.getActivityInfo().getActivityId());
            //事件配置
            for (SonHaiEventConfig eventConfig : config.getEventConfigMap().values()) {
                SonHaiProto.SonHaiEventConfig.Builder eventConfigBuilder = SonHaiActivityPb.buildSonHaiEventConfig(eventConfig, player.getLanguage());
                builder.addEventConfigs(eventConfigBuilder);
            }
            //区域配置
            for (SonHaiFloorConfig floorConfig : config.getFloorConfigMap().values()) {
                SonHaiProto.SonHaiFloorConfig.Builder floorConfigBuilder = SonHaiActivityPb.buildSonHaiFloorConfig(floorConfig, player.getLanguage());
                builder.addFloorConfigs(floorConfigBuilder);
            }
            //Buff配置
            for (SonHaiBuffConfig buffConfig : config.getBuffConfigMap().values()) {
                SonHaiProto.SonHaiBuffConfig.Builder buffConfigBuilder = SonHaiActivityPb.buildSonHaiBuffConfig(buffConfig, player.getLanguage());
                builder.addBuffConfigs(buffConfigBuilder);
            }
            //怪配置
            for (SonHaiMonsterConfig monsterConfig : config.getMonsterConfigMap().values()) {
                SonHaiProto.SonHaiMonsterConfig.Builder monsterConfigBuilder = SonHaiActivityPb.buildSonHaiMonsterConfig(monsterConfig, player.getLanguage());
                builder.addMonsterConfigs(monsterConfigBuilder);
            }
            //蛋配置
            for (SonHaiEggConfig eggConfig : config.getEggConfigMap().values()) {
                SonHaiProto.SonHaiEggConfig.Builder eggConfigBuilder = SonHaiActivityPb.buildSonHaiEggConfig(eggConfig, player.getLanguage());
                builder.addEggConfigs(eggConfigBuilder);
            }
            //地图配置
            for (SonHaiMapConfig mapConfig : config.getMapConfigMap().values()) {
                SonHaiProto.SonHaiMapConfig.Builder mapConfigBuilder = SonHaiActivityPb.buildSonHaiMapConfig(mapConfig);
                builder.addMapConfigs(mapConfigBuilder);
            }
            //推送
            player.sendPacket(Protocol.U_SON_HAI_PUSH_CONFIG_MSG, builder);
        }
    }

    /**
     * 同步玩家数据
     * @param activityId
     */
    public void syncUserData(int activityId) {
        SonHaiServerUserData userData = this.getUserData(activityId);
        if (userData != null) {
            SonHaiProto.SonHaiServerUserData.Builder userDataBuilder = SonHaiActivityPb.buildSonHaiServerUserData(userData);
            player.sendPacket(Protocol.U_SON_HAI_SYNC_SERVER_USER_DATA, userDataBuilder);
        }
    }

    /**
     * 判断触发礼包是否可购买
     * @param activityId
     * @param mallId
     * @return
     */
    public boolean checkTriggerMallCanBuy(int activityId, int mallId) {
        //判断玩家是否存在
        SonHaiServerUserData userData = this.userDataMap.get(activityId);
        if (userData == null) {
            return false;
        }
        //礼包是否存在
        SonHaiUserMallData userMallData = userData.getMallDataMap().get(mallId);
        if (userMallData == null) {
            return false;
        }
        //是否过期
        if (System.currentTimeMillis() > userMallData.getEffectTime()) {
            return false;
        }
        return userMallData.getNum() > 0;
    }

    /**
     * 减少礼包数量
     * @param activityId
     * @param mallId
     */
    public synchronized void reTriggerMallNum(int activityId, int mallId) {
        //判断玩家是否存在
        SonHaiServerUserData userData = this.userDataMap.get(activityId);
        if (userData == null) {
            return;
        }
        SonHaiUserMallData userMallData = userData.getMallDataMap().get(mallId);
        if (userMallData == null) {
            return;
        }
        int newNum = Math.max(userMallData.getNum() - 1, 0);
        userMallData.setNum(newNum);
        //同步玩家信息
        this.syncUserData(activityId);
    }

    /**
     * 添加触发礼包
     * @param activityId
     */
    private synchronized void addTriggerMall(int activityId) {
        //判断礼包是否存在
        SonHaiServerUserData userData = this.userDataMap.get(activityId);
        if (userData == null) {
            return;
        }
        //配置
        SonHaiConfig config = SonHaiActivityMgr.getSonHaiConfig(activityId);
        if (config == null) {
            return;
        }
        //获取触发礼包
        int vipLevel = VipMgr.getVipLv(player.getUserInfo().getVipExp());
        int mallId = config.randomTriggerMallId(vipLevel);
        if (mallId <= 0) {
            return;
        }
        //玩家注入触发礼包
        long now = System.currentTimeMillis();
        long newEffectTime = now + config.getMallKeepTime() * 1000L;
        SonHaiUserMallData userMallData = userData.getMallDataMap().get(mallId);
        if (userMallData == null || now > userMallData.getEffectTime()) {
            userMallData = new SonHaiUserMallData(mallId, 1, newEffectTime);
        } else {
            userMallData.setNum(userMallData.getNum() + 1);
            userMallData.setEffectTime(newEffectTime);
        }
        userData.addMallData(userMallData);
        //同步一下区服玩家数据
        this.syncUserData(activityId);
    }

    /**
     * 解析出奖励（该函数为递归函数，递归结束条件为：extraPlotDataList未空）
     * @param activityId
     * @param exploreResult
     * @return
     */
    private Property parseReward(int activityId, SonHaiProto.SonHaiExploreResult exploreResult) {
        Property reward = new Property();
        if (exploreResult.hasReward() && !StringUtils.isNullOrEmpty(exploreResult.getReward())) {
            Property rewardItem = PropertyHelper.parseStringToProperty(exploreResult.getReward());
            reward.addProperty(rewardItem);
            //额外的地块
            for (SonHaiProto.SonHaiExploreResult extraExploreResult : exploreResult.getExtraPlotDataListList()) {
                Property extraRewardItem = parseReward(activityId, extraExploreResult);
                reward.addProperty(extraRewardItem);
            }
        }
        //判断是否是触发礼包事件
        if (exploreResult.hasPlotData() && exploreResult.getPlotData().getType() == SonHaiPlotTypeEnum.PLOT_TYPE_15.getType()) {
            //添加礼包
            this.addTriggerMall(activityId);
        }
        return reward;
    }

    /**********************************************协议********************************************/

    /**
     * 进入活动
     * @param activityId
     */
    public void enterActivity(int activityId) throws BusinessException {
        //跨服协议信息
        SonHaiProto.SonHaiCrossEnterActivityReqMsg.Builder reqMsgBuilder = SonHaiProto.SonHaiCrossEnterActivityReqMsg.newBuilder();
        reqMsgBuilder.setActivityId(activityId);
        reqMsgBuilder.setLanguage(player.getLanguage());
        //获取玩家baseInfo
        UserBaseInfo userBaseInfo = UserMgr.parseUserBaseInfo(player.getUserInfo(), GameServer.getInstance().getServerId());
        reqMsgBuilder.setUserInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));

        //判断门客是否大于5个
        if (player.getModule(PatronsModule.class).getUserPatronsMap().size() < 5) {
            throw new BusinessException(GameErrorCode.E_SON_HAI_PATRONS_NOT_FULL);
        }

        //获取前30门客战力
        long power = this.getPower(activityId);
        reqMsgBuilder.setPower(power);

        //门客天赋技能加成
        int talentAddition = 0;
        Map<Integer, UserPatrons> userPatronsMap = player.getModule(PatronsModule.class).getUserPatronsMap();
        for (UserPatrons patrons : userPatronsMap.values()) {
            for (UserPatronsSkill patronsSkill : patrons.getSkillList()) {
                //天赋技能
                if (patronsSkill.getType() == ePatronsSkillType.Talent.getValue()) {
                    SkillInfo skillInfo = SkillMgr.getSkillInfo(patronsSkill.getSkillId());
                    //山海战力加成技能
                    if (skillInfo.getType() == eSkillType.SonHaiPowerAddition.getValue()) {
                        talentAddition += SkillMgr.getSkillAddition(skillInfo, patronsSkill.getSkillLv());
                    }
                }
            }
        }
        reqMsgBuilder.setTalentAddition(talentAddition);

        //上跨服
        player.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_ENTER_ACTIVITY, reqMsgBuilder, reqMsgBuilder.getActivityId());
        //同步区服玩家数据
        this.syncUserData(activityId);
    }

    /**
     * 获取战力
     * @param activityId
     * @return
     */
    public long getPower(int activityId) {
        SonHaiConfig sonHaiConfig = SonHaiActivityMgr.getSonHaiConfig(activityId);
        //获取前30门客战力
        long power = 0;
        List<UserPatrons> topAbilityPatrons = player.getModule(PatronsModule.class).getTopAbilityPatrons(30);
        for (UserPatrons patrons : topAbilityPatrons) {
            //转换计算
            long patronsPower = sonHaiConfig.transformPatronsPower(patrons.getAbility().longValue());
            power += patronsPower;
        }
        return power;
    }

    /*****************************************跨服返回*********************************************************/

    /**
     * 探索-跨服返回
     * @param respMsg
     */
    public void exploreFromCross(SonHaiProto.SonHaiExploreRespMsg respMsg) {
        if (respMsg.hasExploreResult()) {
            Property reward = this.parseReward(respMsg.getActivityId(), respMsg.getExploreResult());
            //添加奖励
            player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.SonHai, eLogMoneyType.SonHaiExploreWinReward);
        }
        //回包
        player.sendPacket(Protocol.U_SON_HAI_EXPLORE, respMsg.toBuilder());
    }
}
